
class IOClient extends EventEmitter{
    constructor(uri) {
        this.uri = uri;
        this.isConnect = false;
    }

    // 数据接收
    _onmessage = (e) => {        
        let ret = JSON.parse(e.data)
        if (!ret) {
            //heartCheck.reset()
        } else {
            super.emit(ret.e, ret.args)
        }
    }    
    
    // 初始化websocket
    create = () => {              
    }
    close = (e) => {}
    _open = () => {}

    // 数据发送
    emit = (e, ...args) => {
        if (!isConnect) {
            // 若未开启 ，则等待1s后重新调用
            setTimeout(function () {
                emit(e, args)
            }, 1000)

            return;
        } 
        
        // 若是ws开启状态
        _io_send(JSON.stringify({e:e, args:args}));
    }
}


class WsClient extends IOClient {
    constructor(uri) {
        super(uri);
        this.websock = null;        
    }

    // 初始化websocket
    create = () => {
        super.create();

        this.websock = new WebSocket(uri)
        this.websock.binaryType = 'arraybuffer';
        this.websock.onmessage = function (e) {
            this.onmessage(e)
        }

        this.websock.onclose = function (e) {
            this.close(e)
        }
        this.websock.onopen = function () {
            this.isConnect = true;
            this._open()
//          this.heartCheck.start();
        }
        // 连接发生错误的回调方法
        this.websock.onerror = function () {
            console.log('WebSocket连接发生错误')
            this.isConnect = false; //连接断开修改标识
            //this.reconnect(); //连接错误 需要重连
        }
    }
    
    _io_send = (data) => {
        this.websock.send(data);
    }
}

// 使用ipfs来组织lalm的发布和订阅
class IpfsChannelService {
    constructor(alm) {
        this.room_ = null;
        this.alm_ = alm;        
    }
    
    // 初始化websocket
    create = () => {
        async function build () {
            const ipfs = await window.IpfsCore.create({
          //  const ipfs = await IPFS.create({
              repo: "libName" + Math.random(),
              EXPERIMENTAL: {
                pubsub: true
              },
              config: {
                Addresses: {
                  Swarm: [
                    '/dns4/wrtc-star1.par.dwebops.pub/tcp/443/wss/p2p-webrtc-star/',
                    '/dns4/wrtc-star2.sjc.dwebops.pub/tcp/443/wss/p2p-webrtc-star/',
                    '/dns4/webrtc-star.discovery.libp2p.io/tcp/443/wss/p2p-webrtc-star/'
                  ]
                }
              }
            })
        
            this.room = new PubSubRoom.PubSubRoom(ipfs, this.roomId, 'u1')
            this.room.on('peer joined', (peer) => {
                isConnect = true;
                console.log('Peer joined the room', peer)
            })

            this.room.on('peer left', (peer) => {
                console.log('Peer left...', peer)
            })

            // now started to listen to room
            this.room.on('subscribed', () => {
                isConnect = true;
                console.log('Now connected!')
            })

            this.room.on('message', (msg) => {
                console.log('received msg: ', msg)
                
                  /// 实际上目前用于发送alm创建/退出信令数据到（转发服务器）
                switch (msg.e) {
                    case 'signal' :
                        this.room.peer_send(args[1], args)
                    case 'create':
                        this.room.broadcast(args)
                    case 'join':
                        msg.data 
                        this.room.peer_send(msg.from, {e:'joinResp', data:[ret, layno, members]})
                    case 'joinResp':
                        this.room._onJoin(e.)
                    case 'quit':
                        this.room.peer_send(rootId)
                    default:
                    {
                    }
                }
            })
        }

        build();
    }


    create() {

    }
    join() {
        this.room_.peer_send(this.alm_.getRootId(), {e:'join', data:[this.alm_.getSelfId(), this.alm_.id()] })
    }
    
    _io_send = (data) => {
        this.websock.send(data);
    }

    }
  
        this.room.on(e, callback);
    }

}

class IpfsClient extends IOClient {
    constructor(uri) {
        super(uri);
        this.roomId = uri;
        this.room = null;        
    }

    // 初始化websocket
    create = () => {
        super.create();

        async function build () {
            const ipfs = await window.IpfsCore.create({
          //  const ipfs = await IPFS.create({
              repo: "libName" + Math.random(),
              EXPERIMENTAL: {
                pubsub: true
              },
              config: {
                Addresses: {
                  Swarm: [
                    '/dns4/wrtc-star1.par.dwebops.pub/tcp/443/wss/p2p-webrtc-star/',
                    '/dns4/wrtc-star2.sjc.dwebops.pub/tcp/443/wss/p2p-webrtc-star/',
                    '/dns4/webrtc-star.discovery.libp2p.io/tcp/443/wss/p2p-webrtc-star/'
                  ]
                }
              }
            })
        
            this.room = new PubSubRoom.PubSubRoom(ipfs, this.roomId, 'u1')
            this.room.on('peer joined', (peer) => {
                isConnect = true;
                console.log('Peer joined the room', peer)
            })

            this.room.on('peer left', (peer) => {
                console.log('Peer left...', peer)
            })

            // now started to listen to room
            this.room.on('subscribed', () => {
                isConnect = true;
                console.log('Now connected!')
            })

            this.room.on('message', (msg) => {
                console.log('received msg: ', msg)
            })           
        }

        build();
    }
    
    _io_send = (data) => {
        this.websock.send(data);
    }

     // 数据发送
     emit = (e, ...args) => {
        if (!isConnect) {
            // 若未开启 ，则等待1s后重新调用
            setTimeout(function () {
                emit(e, args)
            }, 1000)

            return;
        }
        
        /// 实际上目前用于发送alm创建/退出信令数据到（转发服务器）
        switch (e) {
            case 'signal' :
                if (args.length < 2) {
                    console.log('no signal parameter')
                    return;
                }
                this.room.peer_send(args[1], args)
            case 'create':
                this.room.broadcast(args)
            case 'join':
                this.room.peer_send(rootId, args)
            case 'quit':
                this.room.peer_send(rootId)
            default:
            {
            }
        }
    }

    // 处理收到的数据
    on = (e, callback) => {
        switch (e) {
            case 'signal' :
                if (args.length < 2) {
                    console.log('no signal parameter')
                    return;
                }
                this._onmessage({data:{
                    e:'signal',
                    args: []
                }})
            case 'create':
                this.room.broadcast(args)
            case 'join':
            case 'quit':
            default:
            {
            }
        }

        this.room.on(e, callback);
    }
}

////////////////////////////////////////////////////////////////////////
//////////////////////////SocketIOClient////////////////////////////////
////////////////////////////////////////////////////////////////////////
class SocketIOClient extends IOClient {
    constructor(uri) {
        super(uri);
        this.msgChannel_ = null;        
    }

    create = () => {
        super.create();
        this.msgChannel_ = io.connect(this.uri);//("ws://" + this.SERVER_IP + ":7000");
    }

     // 数据发送
     emit = (e, ...args) => {
        if (!isConnect) {
            // 若未开启 ，则等待1s后重新调用
            setTimeout(function () {
                emit(e, args)
            }, 1000)

            return;
        } 

        this.msgChannel_.emit(e, args);
    }

    // 处理收到的数据
    on = (e, callback) => {
        this.msgChannel_.on(e, callback);
    }
}
